// [[ OnflowGenerator File UUID: 89422067fa8e49f0baecaa1f4529a59d  ]]
package com.itdct.onflow.system.api.service

import com.itdct.onflow.core.constant.CommonString
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.extend.*
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.api.entity.SysApiEntity
import com.itdct.onflow.system.api.entity.SysApiMenuEntity
import com.itdct.onflow.system.api.manager.SysApiManager
import com.itdct.onflow.system.api.mapper.SysApiMapper
import com.itdct.onflow.system.api.mapper.SysApiMenuMapper
import com.itdct.onflow.system.api.qo.SysApiEditQo
import com.itdct.onflow.system.api.qo.SysApiSearchQo
import com.itdct.onflow.system.api.vo.SysApiDetailVo
import com.itdct.onflow.system.api.vo.SysApiListVo
import com.itdct.onflow.system.common.base.BaseSysService
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.extend.dict
import com.itdct.onflow.system.menu.mapper.SysMenuMapper
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

/**
 * @author DCTANT
 * @date 2025-09-01 15:08:45
 * @version 1.0
 * @description 系统接口服务
 */
@Service
class SysApiService(
    val sysApiMapper: SysApiMapper,
    val sysApiManager: SysApiManager,
    val sysApiMenuMapper: SysApiMenuMapper,
    val sysMenuMapper: SysMenuMapper
) : BaseSysService() {

    @Transactional(rollbackFor = [Exception::class])
    fun add(qo: SysApiEditQo, context: Context): RespVo<Long> {
        val addEntity = qo.toEntity(SysApiEntity::class.java)
        val id = sysApiMapper.insertEx(addEntity)
        return success(id)
    }

    @Transactional(rollbackFor = [Exception::class])
    fun update(qo: SysApiEditQo, context: Context): RespVo<Unit> {
        val updateEntity = sysApiMapper.selectByIdEx(qo.id)
        qo.injectValue(updateEntity)
        sysApiMapper.updateEx(updateEntity)
        return success()
    }

    fun delete(qo: SysApiEditQo, context: Context): RespVo<Unit> {
        val ids = qo.ids ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_DELETE_ID_LIST)
        val deleteEntities = sysApiMapper.selectByIdsEx(ids)
        sysApiMapper.deleteBatchEx(deleteEntities)
        return success()
    }

    fun detail(qo: SysApiSearchQo, context: Context): RespVo<SysApiDetailVo> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val vo = sysApiMapper.findById(id) ?: fail(CommonString.ENTITY_NOT_FOUND_USAGE("系统接口", id))
        return success(vo.dict())
    }

    fun page(qo: SysApiSearchQo, context: Context): RespPageVo<SysApiListVo> {
        startPage(context)
        val pageData = sysApiMapper.findByList(qo)
        return successPage(pageData.dict())
    }

    fun refreshApiRole(context: Context): RespVo<Unit> {
        sysApiManager.refreshRoleApi()
        return success()
    }

    fun autoBindApiMenu(context: Context): RespVo<Unit> {
        val sysApiEntities = sysApiMapper.selectAll()
        val sysApiMenuEntities = sysApiMenuMapper.selectAll()
        val apiMenuListMap = sysApiMenuEntities.groupBy { it.apiId }
        val sysMenuEntities = sysMenuMapper.selectAll()
        val apiMenuEntities = ArrayList<SysApiMenuEntity>()
        for (sysApiEntity in sysApiEntities) {
            val apiId = sysApiEntity.id!!
            val apiMenuList = apiMenuListMap[apiId]
            if (apiMenuList != null && apiMenuList.isNotEmpty()) {
                continue
            }
            val url = sysApiEntity.url
            var temp = url
            if (url.startsWith("/")) {
                temp = url.substring(1)
            }
            val split = temp.split("/")
            if (split.size != 3) {
                continue
            }
            val apiSuffix = onflowConfig.apiSuffix
            val menuName = split[1].substring(0, 1).uppercase() + split[1].substring(1)
            val apiName = split[2]
            when (apiName) {
                "add.$apiSuffix" -> {
                    sysMenuEntities.filter {
                        it.name == "${menuName}Add"
                    }.firstOrNull()?.also {
                        addToApiMenuList(apiMenuEntities, apiId, it.id!!)
                    }
                }

                "detail.$apiSuffix",
                "update.$apiSuffix" -> {
                    sysMenuEntities.filter {
                        it.name == "${menuName}Edit"
                    }.firstOrNull()?.also {
                        addToApiMenuList(apiMenuEntities, apiId, it.id!!)
                    }
                }

                "page.$apiSuffix",
                "delete.$apiSuffix" -> {
                    sysMenuEntities.filter {
                        it.name == "${menuName}Page"
                    }.firstOrNull()?.also {
                        addToApiMenuList(apiMenuEntities, apiId, it.id!!)
                    }
                }
            }
        }
        sysApiMenuMapper.saveBatch(apiMenuEntities)
        return success()
    }

    fun addToApiMenuList(apiMenuEntities: ArrayList<SysApiMenuEntity>, apiId: Long, menuId: Long) {
        val sysApiMenuEntity = SysApiMenuEntity()
        sysApiMenuEntity.apiId = apiId
        sysApiMenuEntity.menuId = menuId
        sysApiMenuEntity.platformType = onflowConfig.platformType
        apiMenuEntities.add(sysApiMenuEntity)
    }

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]

    fun selectNameList(qo: SysApiSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysApiMapper.selectNameList(qo)
        return success(vos)
    }

    fun selectUrlList(qo: SysApiSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysApiMapper.selectUrlList(qo)
        return success(vos)
    }
// [[ OnflowGenerator Range (- selectFunctions -) End ]]
}